<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>继承</title>
</head>

<body>
    <script>
        // 借用构造函数继承:子类构造函数里通过call执行父类构造函数；
        // 子类可以拿到父类的属性；问题：父类原型对象中的方法无法继承
        function Parent1() {
            this.name = 'parent1'
        }
        function Child1() {
            Parent1.call(this)
            this.type = 'child1'
        }
        console.log(new Child1())

        // 原型链继承——将子类的原型指向父类的实例；可以通过原型链获取父类的属性和父类原型上的方法
        // 原型上的属性是公用的，引用类型会统一改变
        function Parent2() {
            this.name = 'parent2';
            this.play = [1, 2, 3]
        }
        function Child2() {
            this.type = 'child2';
        }
        Child2.prototype = new Parent2();
        console.log(new Child2())

        // 组合继承 前两种结合 即在子类中执行父类的构造函数；也通过改变原型指向父类实例对象继承父类的原型方法
        // 问题：父类的构造函数指向了两次（子类函数中；创建原型对象）
        function Parent3() {
            this.name = 'parent3';
            this.play = [1, 2, 3];
        }
        function Child3() {
            Parent3.call(this);
            this.type = 'child3';
        }
        Child3.prototype = new Parent3();
        var s3 = new Child3();
        var s4 = new Child3();
        s3.play.push(4);
        console.log(s3.play, s4.play);

        // 原型式继承 优化组合继承；直接将父类的原型赋值给子类的原型；
        // 问题：子类实例的原型就直接是父类；子类的构造函数也是父类的构造函数
        function Parent4() {
            this.name = 'parent4';
            this.play = [1, 2, 3];
        }
        function Child4() {
            Parent4.call(this);
            this.type = 'child4';
        }
        Child4.prototype = Parent4.prototype;

        // 寄生式继承

        // 寄生组合继承 约等于ES6的extends
        // 子类执行父类函数；通过object.create方法，将子类的原型指向一个空对象，空对象的原型指向父类的原型；
        // 将子类的原型的构造函数指向子类函数本身；
        function Parent5() {
            this.name = 'parent5';
            this.play = [1, 2, 3];
        }
        function Child5() {
            Parent5.call(this);
            this.type = 'child5';
        }
        Child5.prototype = Object.create(Parent5.prototype);
        Child5.prototype.constructor = Child5;

    </script>
</body>

</html>